package com.gao.transportapi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gao.transportapi.common.cache.ApiKeyCache;
import com.gao.transportapi.common.convention.errorcode.BaseErrorCode;
import com.gao.transportapi.common.convention.exception.ClientException;
import com.gao.transportapi.common.convention.exception.ServiceException;
import com.gao.transportapi.common.convention.result.PageDTO;
import com.gao.transportapi.pojo.dto.AccountUpdateDTO;
import com.gao.transportapi.pojo.entity.Accounts;
import com.gao.transportapi.mapper.AccountsMapper;
import com.gao.transportapi.pojo.query.AccountQuery;
import com.gao.transportapi.pojo.vo.AccountBalanceVO;
import com.gao.transportapi.pojo.vo.AccountVO;
import com.gao.transportapi.service.IAccountsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * SILICONFLOW平台账户及API密钥管理表 服务实现类
 * </p>
 *
 * @author GWX.cz
 * @since 2025-06-20
 */
@Service
@Slf4j
public class AccountsServiceImpl extends ServiceImpl<AccountsMapper, Accounts> implements IAccountsService {

    @Resource
    private ApiKeyCache apiKeyCache;

    @Resource
    private RestTemplate restTemplate;

    @Value("${silicon.flow.api.base-url}")
    private String targetApiBaseUrl;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateAccounts(List<String> keyList) {
        if (keyList == null || keyList.isEmpty()) {
            return;
        }

     

        // 批量创建账户
        List<Accounts> accountsAddList = new ArrayList<>();
        for (String key : keyList) {
            Accounts accounts = new Accounts();
            accounts.setIsActive(false);
            accounts.setPlatformType("SILICONFLOW");
            accounts.setPlatformKey(key);
            accounts.setBalance(BigDecimal.ZERO); // 初始余额设置为0
            accounts.setCreatedTime(LocalDateTime.now());
            accounts.setUpdatedTime(LocalDateTime.now());
            accounts.setIsDeleted(false);

            accountsAddList.add(accounts);
        }

        // 批量保存
        try {
            saveBatch(accountsAddList);
            
            // 获取所有新创建账户的ID
            List<Integer> newAccountIds = accountsAddList.stream()
                    .map(Accounts::getId)
                    .collect(Collectors.toList());
            
            // 调用批量更新余额的方法
            batchUpdateAccountsBalance(newAccountIds);
        } catch (Exception e) {
            log.error("批量创建账户失败", e);
            throw new ServiceException("批量创建账户失败: " + e.getMessage());
        }
    }

    @Override
    public void deleteAccountByKey(String key) {
        try {
            // 通过密钥查找并删除账户
            LambdaQueryWrapper<Accounts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Accounts::getPlatformKey, key)
                    .eq(Accounts::getIsDeleted, false);
            
            // 使用remove方法直接删除
            boolean removed = remove(queryWrapper);
            
            if (!removed) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("删除账户失败: " + e.getMessage(), BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public void deleteAccountById(Integer id) {
        try {
            // 直接更新is_deleted字段
            LambdaUpdateWrapper<Accounts> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Accounts::getId, id)
                    .eq(Accounts::getIsDeleted, false)
                    .set(Accounts::getIsDeleted, true);
            
            boolean updated = update(updateWrapper);
            if (!updated) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("删除账户失败", BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public AccountVO updateAccountById(AccountUpdateDTO accountUpdateDTO) {
        // 直接尝试更新，如果失败会抛出异常
        try {
            Integer id = accountUpdateDTO.getId();
            if (id == null) {
                throw new ClientException("账户ID不能为空", BaseErrorCode.CLIENT_ERROR);
            }
            
            // 创建账户对象并设置ID
            Accounts account = new Accounts();
            BeanUtils.copyProperties(accountUpdateDTO, account);
            account.setId(id);
            
            // 更新账户信息，并检查是否成功
            boolean updated = updateById(account);
            if (!updated) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
            
            // 更新成功后，获取最新的账户信息
            account = getById(id);
            return convertToVO(account);
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("更新账户失败: " + e.getMessage(), BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public AccountVO updateAccountByKey(AccountUpdateDTO accountUpdateDTO) {
        try {
            // 检查密钥是否存在
            String key = accountUpdateDTO.getPlatformKey();
            if (key == null || key.isEmpty()) {
                throw new ClientException("平台密钥不能为空", BaseErrorCode.CLIENT_ERROR);
            }
            
            // 通过密钥构建更新条件
            LambdaUpdateWrapper<Accounts> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Accounts::getPlatformKey, key)
                    .eq(Accounts::getIsDeleted, false);
            
            // 创建账户对象并复制属性
            Accounts account = new Accounts();
            BeanUtils.copyProperties(accountUpdateDTO, account);
            account.setPlatformKey(key); // 确保密钥不变
            
            // 直接更新
            boolean updated = update(account, updateWrapper);
            
            if (!updated) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
            
            // 获取更新后的账户信息
            LambdaQueryWrapper<Accounts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Accounts::getPlatformKey, key)
                    .eq(Accounts::getIsDeleted, false);
            account = getOne(queryWrapper);
            
            // 转换为VO并返回
            return convertToVO(account);
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("更新账户失败: " + e.getMessage(), BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public PageDTO<AccountVO> listAccounts(AccountQuery query) {
        // 构建查询条件
        LambdaQueryWrapper<Accounts> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Accounts::getIsDeleted, false);

        // 添加可选的过滤条件
        if (query.getPlatformType() != null && !query.getPlatformType().isEmpty()) {
            queryWrapper.eq(Accounts::getPlatformType, query.getPlatformType());
        }

        if (query.getIsActive() != null) {
            queryWrapper.eq(Accounts::getIsActive, query.getIsActive());
        }

        // 排序
        queryWrapper.orderByDesc(Accounts::getUpdatedTime);

        // 执行分页查询
        Page<Accounts> page = new Page<>(query.getPageNo(), query.getPageSize());
        Page<Accounts> accountPage = page(page, queryWrapper);

        // 转换为VO
        List<AccountVO> accountVOList = accountPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 构建返回结果
        PageDTO<AccountVO> pageDTO = new PageDTO<>();
        pageDTO.setList(accountVOList);
        pageDTO.setTotal(accountPage.getTotal());
        return pageDTO;
    }

    @Override
    public AccountVO getAccountById(Integer id) {
        try {
            Accounts account = getById(id);
            if (account == null || account.getIsDeleted()) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
            return convertToVO(account);
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("获取账户失败: " + e.getMessage(), BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public AccountVO getAccountByKey(String key) {
        try {
            LambdaQueryWrapper<Accounts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Accounts::getPlatformKey, key)
                    .eq(Accounts::getIsDeleted, false);
            Accounts account = getOne(queryWrapper);
    
            if (account == null) {
                throw new ClientException("账户不存在或已删除", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
            }
    
            return convertToVO(account);
        } catch (Exception e) {
            if (e instanceof ClientException) {
                throw e;
            }
            throw new ClientException("获取账户失败: " + e.getMessage(), BaseErrorCode.CLIENT_ERROR);
        }
    }

    @Override
    public String getRandomActiveAccount(String platformType) {
        // 使用ApiKeyCache中维护的缓存获取随机活跃账户
        return apiKeyCache.getApiKey(platformType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AccountBalanceVO> batchUpdateAccountsBalance(List<Integer> accountIds) {



        // 查询指定ID的账户信息
        List<Accounts> accountList = listByIds(accountIds);
        if (accountList.isEmpty()) {
            throw new ClientException("未找到指定的账户", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
        }

        // 过滤出已激活且未删除的账户
        accountList = accountList.stream()
                .filter(account -> !account.getIsDeleted() && account.getIsActive())
                .collect(Collectors.toList());

        if (accountList.isEmpty()) {
            throw new ClientException("未找到活跃的账户", BaseErrorCode.CLIENT_RESOURCE_NOT_FOUND);
        }

        List<AccountBalanceVO> resultList = new ArrayList<>();

        // 对每个账户调用API获取余额
        for (Accounts account : accountList) {
            try {
                // 获取账户的平台密钥
                String apiKey = account.getPlatformKey();

                // 调用平台API获取余额
                BigDecimal balance = getBalanceFromPlatform(apiKey);

                // 更新本地数据库中的余额
                account.setBalance(balance);
                updateById(account);

                // 构建返回结果
                AccountBalanceVO balanceVO = new AccountBalanceVO();
                BeanUtils.copyProperties(account, balanceVO);

                // 密钥脱敏处理
                String maskedKey = maskApiKey(apiKey);
                balanceVO.setPlatformKey(maskedKey);

                resultList.add(balanceVO);

                // 标记密钥已使用，更新LRU队列
                apiKeyCache.markKeyAsUsed(apiKey);

            } catch (Exception e) {
                log.error("获取账户余额失败", e);
                // 继续处理下一个账户，不影响整体流程
            }
        }

        return resultList;
    }

    /**
     * 从平台API获取账户余额
     *
     * @param apiKey API密钥
     * @return 账户余额
     */
    private BigDecimal getBalanceFromPlatform(String apiKey) {
        try {
            // 构建目标URL - 硅基流API的用户信息查询接口
            String url = targetApiBaseUrl + "/v1/user/info";

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + apiKey);

            // 创建请求实体
            HttpEntity<String> entity = new HttpEntity<>(headers);

            // 发送请求并获取响应
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

            // 解析响应获取余额
            String responseBody = response.getBody();
            return extractBalanceFromResponse(responseBody);

        } catch (Exception e) {
            throw new ServiceException("获取余额失败: " + e.getMessage());
        }
    }

    /**
     * 从响应中提取余额
     * 响应格式: {"code":20000,"message":"OK","status":true,"data":{"balance":"0.88","totalBalance":"88.88"}}
     *
     * @param responseBody 响应体
     * @return 余额
     */
    private BigDecimal extractBalanceFromResponse(String responseBody) {
        try {
            if (responseBody != null && responseBody.contains("\"data\"")) {
                // 优先提取totalBalance字段（总余额）
                String pattern = "\"totalBalance\"\\s*:\\s*\"([0-9.]+)\"";
                java.util.regex.Pattern r = java.util.regex.Pattern.compile(pattern);
                java.util.regex.Matcher m = r.matcher(responseBody);
                
                if (m.find()) {
                    String balanceStr = m.group(1);
                    return new BigDecimal(balanceStr).setScale(2, java.math.RoundingMode.HALF_UP);
                }
                
                // 如果没有totalBalance，尝试获取balance字段
                pattern = "\"balance\"\\s*:\\s*\"([0-9.]+)\"";
                r = java.util.regex.Pattern.compile(pattern);
                m = r.matcher(responseBody);
                
                if (m.find()) {
                    String balanceStr = m.group(1);
                    return new BigDecimal(balanceStr).setScale(2, java.math.RoundingMode.HALF_UP);
                }
            }
        } catch (Exception e) {
            log.error("解析余额失败", e);
        }
        return BigDecimal.ZERO;
    }

    /**
     * 对API密钥进行脱敏处理
     *
     * @param apiKey 原始API密钥
     * @return 脱敏后的API密钥
     */
    private String maskApiKey(String apiKey) {
        if (apiKey == null || apiKey.length() <= 8) {
            return apiKey;
        }
        return apiKey.substring(0, 4) + "****" + apiKey.substring(apiKey.length() - 4);
    }

    /**
     * 将Accounts实体转换为AccountVO
     *
     * @param account 账户实体
     * @return AccountVO对象
     */
    private AccountVO convertToVO(Accounts account) {
        if (account == null) {
            return null;
        }
        AccountVO vo = new AccountVO();
        BeanUtils.copyProperties(account, vo);
        return vo;
    }
}
